package com.ruoyi.hotel.service.impl;

import java.math.BigDecimal;
import java.util.List;
import java.util.Date;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.OrderNumberUtils;
import com.ruoyi.hotel.domain.HotelHouse;
import com.ruoyi.hotel.domain.vo.DeleteHotelCheckRecord;
import com.ruoyi.hotel.domain.vo.HotelCheckRecord;
import com.ruoyi.hotel.domain.vo.HotelCheckRecordDetail;
import com.ruoyi.hotel.service.IHotelHouseService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.hotel.mapper.HotelCheckHouseRecordMapper;
import com.ruoyi.hotel.domain.HotelCheckHouseRecord;
import com.ruoyi.hotel.service.IHotelCheckHouseRecordService;
import org.springframework.transaction.annotation.Transactional;

/**
 * 入住记录Service业务层处理
 *
 * @author sunye
 * @date 2024-11-15
 */
@Service
public class HotelCheckHouseRecordServiceImpl extends ServiceImpl<HotelCheckHouseRecordMapper, HotelCheckHouseRecord> implements IHotelCheckHouseRecordService
{
    @Autowired
    private HotelCheckHouseRecordMapper hotelCheckHouseRecordMapper;

    @Autowired
    private IHotelHouseService hotelHouseService;

    /**
     * 查询入住记录
     *
     * @param recordId 入住记录主键
     * @return 入住记录
     */
    @Override
    public HotelCheckHouseRecord selectHotelCheckHouseRecordByRecordId(Long recordId)
    {
        return hotelCheckHouseRecordMapper.selectHotelCheckHouseRecordByRecordId(recordId);
    }

    /**
     * 查询入住记录列表
     *
     * @param hotelCheckHouseRecord 入住记录
     * @return 入住记录
     */
    @Override
    public List<HotelCheckHouseRecord> selectHotelCheckHouseRecordList(HotelCheckHouseRecord hotelCheckHouseRecord)
    {
        return hotelCheckHouseRecordMapper.selectHotelCheckHouseRecordList(hotelCheckHouseRecord);
    }

    /**
     * 新增入住记录
     *
     * @param hotelCheckHouseRecord 入住记录
     * @return 结果
     */
    @Override
    public int insertHotelCheckHouseRecord(HotelCheckHouseRecord hotelCheckHouseRecord)
    {
    Date date = DateUtils.getNowDate();
            hotelCheckHouseRecord.setCreateTime(date);
            hotelCheckHouseRecord.setUpdateTime(date);
        return hotelCheckHouseRecordMapper.insert(hotelCheckHouseRecord);
    }

    /**
     * 修改入住记录
     *
     * @param hotelCheckHouseRecord 入住记录
     * @return 结果
     */
    @Override
    public int updateHotelCheckHouseRecord(HotelCheckHouseRecord hotelCheckHouseRecord)
    {
        hotelCheckHouseRecord.setUpdateTime(DateUtils.getNowDate());
        return hotelCheckHouseRecordMapper.updateById(hotelCheckHouseRecord);
    }

    /**
     * 批量删除入住记录
     *
     * @param recordIds 需要删除的入住记录主键
     * @return 结果
     */
    @Override
    public int deleteHotelCheckHouseRecordByRecordIds(Long[] recordIds)
    {
        return hotelCheckHouseRecordMapper.deleteHotelCheckHouseRecordByRecordIds(recordIds);
    }

    /**
     * 删除入住记录信息
     *
     * @param recordId 入住记录主键
     * @return 结果
     */
    @Override
    public int deleteHotelCheckHouseRecordByRecordId(Long recordId)
    {
        return hotelCheckHouseRecordMapper.deleteHotelCheckHouseRecordByRecordId(recordId);
    }

    @Override
    @Transactional
    public int checkInRegister(HotelCheckRecord hotelCheckRecord) {
        List<HotelCheckRecordDetail> hotelCheckRecordList = hotelCheckRecord.getHotelCheckRecordList();
        if(hotelCheckRecordList ==null || hotelCheckRecordList.size()==0){
            throw new ServiceException("请填写登记人员信息");
        }
        Long houseId = hotelCheckRecord.getHouseId();
        HotelHouse hotelHouse = hotelHouseService.getById(houseId);
        if(hotelHouse ==null){
            throw new ServiceException("请选择登记的房间");
        }
        //判断身份证重复
        List<String> idCardStringList = hotelCheckRecordList.stream().map(item -> item.getIdCard()).collect(Collectors.toList());
        long idCardCount = idCardStringList.stream().distinct().count();
        if(idCardStringList.size() != idCardCount){
            throw new ServiceException("身份证号重复，请重新填写");
        }
        for (HotelCheckRecordDetail hotelCheckRecordDetail : hotelCheckRecordList) {
            String idCard = hotelCheckRecordDetail.getIdCard();
            HotelCheckHouseRecord count = hotelCheckHouseRecordMapper.selectCountByIdCard(idCard,null);
            if(count !=null){
                String realName = count.getRealName();
                throw new ServiceException("客户："+realName+" ，身份证号 "+idCard+" 已登记在房间 "+hotelHouse.getHouseNum()+"，请勿重复登记。");
            }
        }
        BigDecimal housePrice = hotelHouse.getHousePrice();
        Long createId = hotelCheckRecord.getCreateId();
        Date date = new Date();
        if(hotelHouse.getHouseStatus() == 2){
            String orderNo = "R" + OrderNumberUtils.createOrderNumber();
            List<HotelCheckHouseRecord> collect = hotelCheckRecordList.stream().map(item -> {
                HotelCheckHouseRecord record = new HotelCheckHouseRecord();
                record.setRecordNum(orderNo);
                record.setHouseId(houseId);
                record.setHousePrice(housePrice);
                record.setRealName(item.getRealName());
                record.setIdCard(item.getIdCard());
                record.setPhone(item.getPhone());
                record.setCreateId(createId);
                record.setOpenTime(date);//开房时间
                record.setCreateTime(date);
                record.setUpdateTime(date);
                return record;
            }).collect(Collectors.toList());
            this.saveBatch(collect);
            //修改为入住状态
            int peopleNumber = hotelCheckRecordList.size();
            LambdaUpdateWrapper<HotelHouse> updateWrapper = new LambdaUpdateWrapper<>();
            updateWrapper.set(HotelHouse::getHouseStatus,3);
            updateWrapper.set(HotelHouse::getPeopleNumber,peopleNumber);
            updateWrapper.eq(HotelHouse::getHouseId, houseId);
            hotelHouseService.update(updateWrapper);
        }else{
            throw new ServiceException("当前房间状态非可入住状态，不能登记");
        }
        return 1;
    }

    @Override
    @Transactional
    public int addCheckInPeople(HotelCheckRecord hotelCheckRecord) {
        List<HotelCheckRecordDetail> hotelCheckRecordList = hotelCheckRecord.getHotelCheckRecordList();
        if(hotelCheckRecordList ==null || hotelCheckRecordList.size()==0){
            throw new ServiceException("请填写登记人员信息");
        }
        //判断身份证重复
        List<String> idCardStringList = hotelCheckRecordList.stream().map(item -> item.getIdCard()).collect(Collectors.toList());
        long idCardCount = idCardStringList.stream().distinct().count();
        if(idCardStringList.size() != idCardCount){
            throw new ServiceException("身份证号重复，请重新填写");
        }
        //添加记录
        List<HotelCheckRecordDetail> addRecotdList = hotelCheckRecordList.stream()
                .filter(item -> item.getUpdateIdentify().equals(1)).collect(Collectors.toList());
        //修改记录
        List<HotelCheckRecordDetail> updateRecotdList = hotelCheckRecordList.stream()
                .filter(item -> item.getUpdateIdentify().equals(2) ).collect(Collectors.toList());
        Long houseId = hotelCheckRecord.getHouseId();
        HotelHouse hotelHouse = hotelHouseService.getById(houseId);
        if(hotelHouse ==null){
            throw new ServiceException("请选择登记的房间");
        }
        BigDecimal housePrice = hotelHouse.getHousePrice();
        Long createId = hotelCheckRecord.getCreateId();
        Date date = new Date();
        if(hotelHouse.getHouseStatus() == 3){
            //添加人员
            if(addRecotdList !=null && addRecotdList.size()>0){
                for (HotelCheckRecordDetail hotelCheckRecordDetail : addRecotdList) {
                       String idCard = hotelCheckRecordDetail.getIdCard();
                        HotelCheckHouseRecord count = hotelCheckHouseRecordMapper.selectCountByIdCard(idCard,null);
                        if(count !=null){
                            String realName = count.getRealName();
                            throw new ServiceException("客户："+realName+" ，身份证号 "+idCard+" 已登记在房间 "+hotelHouse.getHouseNum()+"，请勿重复登记。");
                        }
                }
                List<HotelCheckRecordDetail> recordRecotdList= hotelCheckHouseRecordMapper.selectHotelRecordByHouseId(houseId);
                if(recordRecotdList ==null || recordRecotdList.size()==0){
                    throw new ServiceException("该房间暂无人员居住");
                }
                HotelCheckRecordDetail hotelCheckRecordDetail = recordRecotdList.get(0);
                String recordNum = hotelCheckRecordDetail.getRecordNum();
                Date openTime = hotelCheckRecordDetail.getOpenTime();
                List<HotelCheckHouseRecord> addCollect = addRecotdList.stream().map(item -> {
                HotelCheckHouseRecord record = new HotelCheckHouseRecord();
                record.setRecordNum(recordNum);
                record.setHouseId(houseId);
                record.setHousePrice(housePrice);
                record.setRealName(item.getRealName());
                record.setIdCard(item.getIdCard());
                record.setPhone(item.getPhone());
                record.setCreateId(createId);
                record.setOpenTime(openTime);//开房时间
                record.setCreateTime(date);
                record.setUpdateTime(date);
                return record;
            }).collect(Collectors.toList());
                this.saveBatch(addCollect);
            }
            for (HotelCheckRecordDetail hotelCheckRecordDetail : updateRecotdList) {
                String idCard = hotelCheckRecordDetail.getIdCard();
                Long recordId = hotelCheckRecordDetail.getRecordId();
                HotelCheckHouseRecord count = hotelCheckHouseRecordMapper.selectCountByIdCard(idCard,recordId);
                if(count !=null){
                    String realName = count.getRealName();
                    throw new ServiceException("客户："+realName+" ，身份证号 "+idCard+" 已登记在房间 "+hotelHouse.getHouseNum()+"，请勿重复登记。");
                }
            }
            //修改人员
            if(updateRecotdList !=null && updateRecotdList.size()>0){
                List<HotelCheckHouseRecord> updateCollect = updateRecotdList.stream().map(item -> {
                HotelCheckHouseRecord record = new HotelCheckHouseRecord();
                record.setRecordId(item.getRecordId());
                record.setRealName(item.getRealName());
                record.setIdCard(item.getIdCard());
                record.setPhone(item.getPhone());
                record.setUpdateId(createId);
                record.setUpdateTime(date);
                return record;
                }).collect(Collectors.toList());
                this.updateBatchById(updateCollect);
            }
            //修改为入住人数
            int peopleNumber = hotelCheckRecordList.size();
            LambdaUpdateWrapper<HotelHouse> updateWrapper = new LambdaUpdateWrapper<>();
            updateWrapper.set(HotelHouse::getPeopleNumber,peopleNumber);
            updateWrapper.eq(HotelHouse::getHouseId, houseId);
            hotelHouseService.update(updateWrapper);
        }else{
            throw new ServiceException("当前房间状态非已入住状态，不能添加人员");
        }
        return 1;
    }

    @Override
    @Transactional
    public int deleteCheckInPeople(DeleteHotelCheckRecord deleteHotelCheckRecord) {
        Long houseId = deleteHotelCheckRecord.getHouseId();
        HotelHouse hotelHouse = hotelHouseService.getById(houseId);
        if(hotelHouse ==null){
            throw new ServiceException("请选择登记的房间");
        }
        if(hotelHouse.getHouseStatus() == 3){
            //删除人员
            LambdaUpdateWrapper<HotelCheckHouseRecord> update = new LambdaUpdateWrapper<>();
            update.set(HotelCheckHouseRecord::getIsLeave,1);
            update.set(HotelCheckHouseRecord::getLeaveTime,new Date());
            update.set(HotelCheckHouseRecord::getLeaveCreateId,deleteHotelCheckRecord.getCreateId());
            update.eq(HotelCheckHouseRecord::getRecordId,deleteHotelCheckRecord.getRecordId());
            this.update(update);
            //修改为入住人数
            List<HotelCheckRecordDetail> recordRecotdList= hotelCheckHouseRecordMapper.selectHotelRecordByHouseId(houseId);
            if(recordRecotdList == null || recordRecotdList.size()==0){
                throw new ServiceException("不能将房间的所有登记人员删除");
            }
            int peopleNumber = recordRecotdList.size();
            LambdaUpdateWrapper<HotelHouse> updateWrapper = new LambdaUpdateWrapper<>();
            updateWrapper.set(HotelHouse::getPeopleNumber,peopleNumber);
            updateWrapper.eq(HotelHouse::getHouseId, houseId);
            hotelHouseService.update(updateWrapper);
        }else{
            throw new ServiceException("当前房间状态非已入住状态，不能删除人员");
        }
        return 1;
    }

    @Override
    public HotelCheckRecord checkInDetail(Long houseId) {
        HotelHouse hotelHouse = hotelHouseService.getById(houseId);
        if(hotelHouse ==null){
            throw new ServiceException("请选择房间");
        }
        HotelCheckRecord record = new HotelCheckRecord();
        List<HotelCheckRecordDetail> hotelCheckRecordList = hotelCheckHouseRecordMapper.selectHotelRecordByHouseId(houseId);
        if(hotelCheckRecordList !=null && hotelCheckRecordList.size()>0){
            record.setCreateTime(hotelCheckRecordList.get(0).getOpenTime());
        }else{
            record.setCreateTime(new Date());
        }
        record.setHotelCheckRecordList(hotelCheckRecordList);
        return record;
    }

    @Override
    @Transactional
    public int confirmCheckOut(Long houseId,Long userId) {
        HotelHouse hotelHouse = hotelHouseService.getById(houseId);
        if(hotelHouse ==null){
            throw new ServiceException("请选择房间");
        }
        if(hotelHouse.getHouseStatus() == 3){
            //修改未打扫状态
            LambdaUpdateWrapper<HotelHouse> updateWrapper = new LambdaUpdateWrapper<>();
            updateWrapper.set(HotelHouse::getHouseStatus,1);
            updateWrapper.set(HotelHouse::getPeopleNumber,0);
            updateWrapper.eq(HotelHouse::getHouseId, houseId);
            hotelHouseService.update(updateWrapper);
            //修改入住记录为离店
            LambdaUpdateWrapper<HotelCheckHouseRecord> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
            lambdaUpdateWrapper.set(HotelCheckHouseRecord::getIsLeave,1);
            lambdaUpdateWrapper.set(HotelCheckHouseRecord::getLeaveCreateId,userId);
            lambdaUpdateWrapper.set(HotelCheckHouseRecord::getLeaveTime,new Date());
            lambdaUpdateWrapper.eq(HotelCheckHouseRecord::getHouseId, houseId);
            lambdaUpdateWrapper.eq(HotelCheckHouseRecord::getIsLeave, 0);
            this.update(lambdaUpdateWrapper);
        }else{
            throw new ServiceException("当前房间状态非已入住状态，不能确认退房");
        }
        return 1;
    }


}
